package cn.lirenyi.user.service.impl;

import cn.lirenyi.basic.exception.BusinessException;
import cn.lirenyi.basic.service.impl.BaseServiceImpl;
import cn.lirenyi.basic.util.MD5Utils;
import cn.lirenyi.basic.util.StrUtils;
import cn.lirenyi.user.Dto.UserDto;
import cn.lirenyi.user.constant.UserConstant;
import cn.lirenyi.user.domain.Logininfo;
import cn.lirenyi.user.domain.User;
import cn.lirenyi.user.mapper.LogininfoMapper;
import cn.lirenyi.user.mapper.UserMapper;
import cn.lirenyi.user.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {

    @Autowired
    private UserMapper UserMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private LogininfoMapper logininfoMapper;

    /*业务逻辑：
    一.校验
			1.1.空校验（前端传来的4个参数不能为空），两次密码是否一致（用前台传来的密码和确认密码来比较，）
            1.2.手机不能被注册
				（直接调用前台写的方法查询数据库是否存在，然后id判断）
            1.3.验证码是否过期
				（redistemplate.opsforvalus.get（key））
            1.4.验证码是否相等	注意不要区分大小写
				（equalsignoreCase比较）
    二.保存数据
			（用写方法把userDto2User值保存给user）
            （用写方法把user2LoginInfo值保存给LoginInfo）
            2.1保存logininfo
				（注入个对象，logininfomapper对象，用该对象调修改方法，返回自增id）
            2.2保存user
				（先把自增id赋值给user的id，用user.setlogininfo_id（logininfo.getId()））

    写个user2LoginInfo方法把userdto2logininfo的参数设置到user里面
    写个方法userDto2User把logininfo的剩下最后一个字段设置给同名字段（BeanUtils.copyProperties(user, loginInfo)//属性同名原则拷贝）*/

    @Transactional
    @Override
    public void register(UserDto userDto) {
        // 校验，非空
        if (StringUtils.isEmpty(userDto.getPassword()) || StringUtils.isEmpty(userDto.getConfirmPwd()) ||
                StringUtils.isEmpty(userDto.getPhone()) || StringUtils.isEmpty(userDto.getVerifyCode())){
            throw new BusinessException("请输入相关信息");
        }
        // 校验密码是否一致
        if (!userDto.getPassword().equals(userDto.getConfirmPwd())){
            throw new BusinessException("两次密码不一致，请重新输入");
        }
        // 查询手机不能被注册
        User userTmp = UserMapper.queryByPhone(userDto.getPhone());
        if (userTmp != null){
            throw new BusinessException("该账号已被注册，请重新输入");
        }
        // 判断验证码是否过期
        Object codeObj = redisTemplate.opsForValue().get(UserConstant.BUSINESS_REGISTER_PREFIX + userDto.getPhone());
        if (codeObj == null){
            throw new BusinessException("该验证码已过期，请重新获取");
        }
        // 验证码是否相等	注意不要区分大小写
        String code = ((String)codeObj).split(":")[0];
        if (!code.equalsIgnoreCase(userDto.getVerifyCode())){
            throw new BusinessException("请输入正确验证码");
        }

        // 保存数据
        User user = userDto2User(userDto);
        Logininfo logininfo = user2LoginInfo(user);
        //1.保存loginInfo
        logininfoMapper.add(logininfo);//返回自增id
        //2.保存user
        user.setLogininfo_id(logininfo.getId());
        UserMapper.add(user);

    }
    private User userDto2User(UserDto userDto){
        User user = new User();
        // 把前台的参数赋值给user
        user.setUsername(userDto.getPhone());
        user.setPhone(userDto.getPhone());
        // 盐值
        String salt = StrUtils.getComplexRandomString(32);
        // 用盐值加密之后的密码
        String md5Pwd = MD5Utils.encrypByMd5(userDto.getPassword() + salt);
        user.setSalt(salt);
        user.setPassword(md5Pwd);
        return user;
    }
    private Logininfo user2LoginInfo(User user) {
        Logininfo logininfo = new Logininfo();
        // 属性同名原则拷贝
        BeanUtils.copyProperties(user, logininfo);
        logininfo.setType(1);
        return logininfo;
    }

    /*@Override
    public void add(User user) {
        //1.设置用户的盐值和密码加密
        initUser(user);
        //复制一个LoginInfo
        Logininfo info =  employee2LoginInfo(user);
        logininfoMapper.add(info);
        user.setLogininfo_id(info.getId());
        UserMapper.add(user);
        super.add(user);
    }

    private Logininfo employee2LoginInfo(User user) {
        Logininfo info = new Logininfo();
        BeanUtils.copyProperties(user,info);
        // 后台员工type应该设置成0
        info.setType(0);
        return info;
    }

    private void initUser(User user) {
        String salt = StrUtils.getComplexRandomString(32);
        String md5Pwd = MD5Utils.encrypByMd5(user.getPassword() + salt);
        user.setSalt(salt);
        user.setPassword(md5Pwd);
    }

    @Override
    public void update(User user) {
        Logininfo logininfo = logininfoMapper.queryById(user.getLogininfo_id());
        if(logininfo != null){
            BeanUtils.copyProperties(user, logininfo);
            logininfoMapper.update(logininfo);
            UserMapper.update(user);
        }
    }

    @Override
    public void del(Long id) {
        User user = UserMapper.queryById(id);
        logininfoMapper.del(user.getLogininfo_id());
        UserMapper.del(id);
    }*/
}
